#!/usr/bin/env zsh

# Prevent recursion when starting a shell in the background
# Also prevent ohmyzsh updates in the background.
[[ -z $_ZGENOM_JUST_INIT ]] || { DISABLE_AUTO_UPDATE=true  && return }

# Show last log if it exists
if [[ -s "$ZGEN_SOURCE/.last_autoupdate_log" ]]; then
    function __zgenom_autoupdate_log() {
        add-zsh-hook -d precmd __zgenom_autoupdate_log
        unfunction __zgenom_autoupdate_log

        printf '\n%s\n--------\n' 'Last zgenom autoupdate log:'
        printf '%s\n' "${(@f)$(<$ZGEN_SOURCE/.last_autoupdate_log)}"
        printf '--------\n'
        printf '' >| "$ZGEN_SOURCE/.last_autoupdate_log"
    }

    # A precmd hook is needed since some terminals swallow output of shell startup.
    autoload -Uz add-zsh-hook
    add-zsh-hook precmd __zgenom_autoupdate_log
fi

autoload -Uz __zgenom_autoupdate
function zgenom-autoupdate() {
    # NOTE: This could be sped up by moving the background check before the
    #       parameter checking.
    #       This only reduces the startup time by ~1ms and
    #       would result in errors not shown in the executing shell but in the
    #       backgrounded shell.
    #       That's why I decided not to keep it this way.
    local self plugin verbose nobg omz deprecated silent
    zparseopts -D -E -self:=self -plugin:=plugin -verbose=verbose v=verbose -no-background=nobg -keep-ohmyzsh=omz -background=deprecated -silent=silent || return

    if [[ -z $omz ]]; then
        : ${DISABLE_AUTO_UPDATE:=true}
    fi

    if [[ -z $self ]] && [[ -z $plugin ]]; then
        if [[ -n $1 && $1 -lt 1 ]]; then
            __zgenom_err "You must specify an integer number of days, greater than zero."
            return 1
        fi
        self=${1:-7}
        plugin=$self
    else
        [[ -n $self ]] && self=$self[2]
        [[ -n $plugin ]] && plugin=$plugin[2]
        if [[ -n $self && $self -lt 1 ]] || [[ -n $plugin && $plugin -lt 1 ]]; then
            __zgenom_err "You must specify an integer number of days, greater than zero."
            return 1
        fi
    fi
    verbose=${verbose:-$ZGENOM_AUTOUPDATE_VERBOSE}

    if [[ -z $nobg ]]; then
        function __zgenom_autoupdate_background() {
            add-zsh-hook -d precmd __zgenom_autoupdate_background
            unfunction __zgenom_autoupdate_background

            # Updating kills the migration process in some terminals...
            # E.g. neovims builtin terminal emulator.
            [[ -z $_ZGENOM_NEEDS_MIGRATION ]] || return 0

            # Retrieve state
            local self=$_ZGENOM_SELF && unset _ZGENOM_SELF
            local plugin=$_ZGENOM_PLUGIN && unset _ZGENOM_PLUGIN
            local verbose=$_ZGENOM_VERBOSE && unset _ZGENOM_VERBOSE
            local silent=$_ZGENOM_SILENT && unset _ZGENOM_SILENT

            # Dispatch update in the background
            (
                local colors=$(git config --global --get 'color.ui')
                if [[ -z $colors || $colors = 'auto' || $colors = 'true' ]]; then
                    function git() { command git -c 'color.ui=always' $@ }
                fi
                # Some plugins (e.g. romkatv/gitstatus) may raise issues with
                # `zsh -il -c exit` since it isn't really an interactive shell.
                # Hence a non interactive shell sourcing .zshrc is used.
                local cmd="source ${${(q)${ZDOTDIR:-$HOME}}//\%/%%}/.zshrc"
                local log=$(
                    __zgenom_autoupdate 2>&1 \
                        && printf 'Recreating init.zsh\n\n' \
                        && _ZGENOM_JUST_INIT=1 zsh -c $cmd 2>&1
                )
                if [[ -z $silent && -n $log ]]; then
                    printf '%s\n\n' $log >| "$ZGEN_SOURCE/.last_autoupdate_log"
                fi
            ) &!
        }

        # Save state
        _ZGENOM_SELF=$self
        _ZGENOM_PLUGIN=$plugin
        _ZGENOM_VERBOSE=$verbose
        _ZGENOM_SILENT=$silent

        # Schedule update right before the first prompt is drawn.
        autoload -Uz add-zsh-hook
        add-zsh-hook precmd __zgenom_autoupdate_background
    else
        # Don't propagate error if not updated
        __zgenom_autoupdate || true
    fi
}

zgenom-autoupdate $@
